package com.kefu.chat.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kefu.basic.mapper.BasicStatusConfigMapper;
import com.kefu.basic.model.BasicStatusConfig;
import com.kefu.chat.model.*;
import com.kefu.chat.service.*;
import com.kefu.chat.vo.*;
import com.kefu.common.context.KefuContext;
import com.kefu.common.controller.AbstractBaseController;
import com.kefu.common.result.Result;
import com.kefu.common.result.ResultGenerator;
import com.kefu.common.util.DateUtils;
import com.kefu.robot.service.RobotDocCommentService;
import com.kefu.sys.mapper.SysUserMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "在线统计接口")
@RestController
@RequestMapping("chat/rpt")
public class ChatReportController extends AbstractBaseController {
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private ChatRptSessionService chatRptSessionService;
    @Resource
    private ChatRptDocHitService chatRptDocHitService;
    @Resource
    private ChatSessionService chatSessionService;
    @Resource
    private ChatReportService chatReportService;
    @Resource
    private ChatAdminStatusService chatAdminStatusService;
    @Resource
    private ChatRptAdminWorkService chatRptAdminWorkService;
    @Autowired
    private ChatSessionMsgService chatSessionMsgService;
    @Autowired
    private ChatCacheService chatCacheService;
    @Resource
    private BasicStatusConfigMapper basicStatusConfigMapper;
    @Resource
    private RobotDocCommentService robotDocCommentService;
    @Resource
    private ChatRptRobotAnswerService chatRptRobotAnswerService;

    @PostMapping("/sessionGroup")
    @ApiOperation(value = "会话统计", notes = "会话统计")
    public Result<ChatRptSession> sessionGroup(@Validated @RequestBody ChatRptSessionGroupVo search) {
        ChatRptSession list = chatRptSessionService.selectGroupList(search);
        return ResultGenerator.genSuccessResult(list);
    }

    @PostMapping("/sessionGroupExport")
    @ApiOperation(value = "导出会话统计", notes = "导出会话统计")
    public void sessionGroupExport(@Validated @RequestBody ChatRptSessionGroupVo search, HttpServletResponse response) throws IOException {
        List<Object[]> exportList = chatRptSessionService.sessionGroupExport(search);
        csvWriter(exportList, response);
    }

    @PostMapping("/sessionStat")
    @ApiOperation(value = "查询会话统计-趋势图", notes = "查询会话统计-趋势图")
    public Result<List<ChatRptSession>> sessionStat(@Validated @RequestBody ChatRptSessionStatVo search) {
        if (search.getResultDateStart()==null|| search.getResultDateEnd()==null) {
            return ResultGenerator.genValidFailResult();
        }
        search.setTenantId(KefuContext.getKefuContext().getTenantId());
        List<ChatRptSession> list = chatSessionService.selectGroupByDate(search);
        return ResultGenerator.genSuccessResult(list);
    }

    @PostMapping("/getAdminWork")
    @ApiOperation(value = "查询客服工作量统计", notes = "查询客服工作量统计")
    public Result<List<ChatRptAdminWork>> getAdminWork(@Validated @RequestBody ChatRptAdminWorkSearchVo search) {
        if (search.getStartTime() == null || search.getEndTime() == null) {
            return ResultGenerator.genValidFailResult();
        }
        search.setTenantId(KefuContext.getKefuContext().getTenantId());
        List<ChatRptAdminWork> list = chatRptAdminWorkService.selectGroupList(search);
        //如果统计时间包含今天，加上当前状态持续时长
        if (search.getEndTime() >= System.currentTimeMillis()) {
            list.forEach(work -> {
                ChatAdmin admin = chatCacheService.getAdmin(work.getAdminId());
                if (admin != null) {
                    if (admin.getStatus() == 1) {
                        int statusDuration = (int) (System.currentTimeMillis() - admin.getStatusTime()) / 1000;
                        work.setOnlineStatusDuration(work.getOnlineStatusDuration() + statusDuration);
                    } else if (admin.getStatus()>1) {
                        int statusDuration = (int) (System.currentTimeMillis() - admin.getStatusTime()) / 1000;
                        work.setBusyStatusDuration(work.getBusyStatusDuration() + statusDuration);
                        String field=String.format("status%dDuration", admin.getStatus());
                        Integer duration=BeanUtil.getProperty(work, field);
                        BeanUtil.setProperty(work, field,duration+statusDuration);
                    }
                }
            });
        }
        return ResultGenerator.genSuccessResult(list);
    }

    @PostMapping("/getAdminWorkExport")
    @ApiOperation(value = "导出客服工作量统计", notes = "导出客服工作量统计")
    public void getAdminWorkExport(@Validated @RequestBody ChatRptAdminWorkSearchVo search, HttpServletResponse response) throws IOException {
        List<Object[]> exportList = chatRptAdminWorkService.adminWorkExport(search);
        csvWriter(exportList, response);
    }

    @PostMapping("/sessionRecord")
    @ApiOperation(value = "查询会话纪录", notes = "查询会话纪录")
    public Result<Page<Map<String, Object>>> sessionRecord(@Validated @RequestBody ChatSessionRptVo search) {
        Page<Map<String, Object>> page = chatSessionService.getSession(search);
        return ResultGenerator.genSuccessResult(page);
    }
    
    @PostMapping("/userSessionRecord")
    @ApiOperation(value = "查询用户会话", notes = "查询用户会话")
    public Result<Page<ChatSession>> userSessionRecord(@Validated @RequestBody ChatUserSessionSearchVo search) {
    	 
    	Page<ChatSession> page = chatSessionService.userSessionRecord(search);
    	return ResultGenerator.genSuccessResult(page);
    }

    @PostMapping("/sessionRecordExport")
    @ApiOperation(value = "导出会话纪录", notes = "导出会话纪录")
    public void sessionRecordExport(@Validated @RequestBody ChatSessionRptVo search, HttpServletResponse response) throws IOException {
        List<Object[]> exportList = chatSessionService.sessionRecordExport(search);
        csvWriter(exportList, response);
    }

    @PostMapping("/sessionMsgExport")
    @ApiOperation(value = "导出会话消息", notes = "导出会话消息")
    public void sessionMsgExport(@Validated @RequestBody ChatSessionSearchVo search, HttpServletResponse response) throws IOException {
        if (search.getStartTimeStart() == null) {
            return;
        }
        if (StrUtil.isNotBlank(search.getOrderField())) {
            search.setOrderField(StrUtil.toUnderlineCase(search.getOrderField()));
        }
        List<ChatSessionMsg> list = chatSessionMsgService.list(Wrappers.lambdaQuery(ChatSessionMsg.class).eq(ChatSessionMsg::getTenantId, KefuContext.getTid())
                .lt(ChatSessionMsg::getMsgTime, search.getStartTimeEnd())
                .gt(ChatSessionMsg::getMsgTime, search.getStartTimeStart())
                .orderByAsc(ChatSessionMsg::getMsgTime).last("limit 30000"));

        List<Object[]> exportList = new ArrayList<>();
        Object[] title = {msg("消息时间"), msg("会话ID"), msg("发送者"), msg("消息内容")};
        exportList.add(title);
        for (ChatSessionMsg i : list) {
            Object[] row = {DateUtil.date(i.getMsgTime()).toString(), i.getSessionId(), i.getSenderName(), i.getMsgContent()};
            exportList.add(row);
        }
        csvWriter(exportList, response);
    }

    @PostMapping("/robotAnswerStat")
    @ApiOperation(value = "查询机器人回答类型统计", notes = "查询机器人回答类型统计")
    public Result<List<ChatRptRobotAnswer>> robotAnswerStat(@Validated @RequestBody ChatRptRobotAnswerSearchVo search) {
        if (search.getResultDateStart()==null||search.getResultDateEnd()==null) {
            return ResultGenerator.genValidFailResult();
        }
        if (DateUtil.isSameDay(new Date(search.getResultDateStart()),new Date(search.getResultDateEnd()))){
            search.setSameDay(true);
        }

        search.setTenantId(KefuContext.getKefuContext().getTenantId());
        List<ChatRptRobotAnswer> list = chatRptRobotAnswerService.selectGroupByDate(search);
        return ResultGenerator.genSuccessResult(list);
    }

    @PostMapping("/robotAnswerStatExport")
    @ApiOperation(value = "导出机器人回答类型统计", notes = "导出机器人回答类型统计")
    public void robotAnswerStatExport(@Validated @RequestBody ChatRptRobotAnswerSearchVo search, HttpServletResponse response) throws IOException {
        if (search.getResultDateStart()==null||search.getResultDateEnd()==null) {
           return;
        }
        if (DateUtil.isSameDay(new Date(search.getResultDateStart()),new Date(search.getResultDateEnd()))){
            search.setSameDay(true);
        }
        search.setTenantId(KefuContext.getTid());
        List<ChatRptRobotAnswer> list = chatRptRobotAnswerService.selectGroupByDate(search);
        List<Object[]> exportList = new ArrayList<>();
        Object[] title = {msg("日期"), msg("时间"), msg("未知回答"), msg("直接回答"), msg("引导回答"), msg("自定义寒暄"), msg("基本寒暄"), msg("互联网寒暄"), msg("Ai大模型回答")};
        exportList.add(title);
        for (ChatRptRobotAnswer i : list) {
            Object[] row = {i.getResultDate(), i.getResultHour(), i.getResultUnknown(), i.getResultDirect(), i.getResultSuggest(), i.getResultCustom(),
                    i.getResultBase(), i.getResultNetwork() , i.getResultAidata()};
            exportList.add(row);
        }
        csvWriter(exportList, response);
    }

    @PostMapping("/docHitStat")
    @ApiOperation(value = "查询机器人词条命中统计", notes = "查询机器人词条命中统计")
    public Result<Page<ChatRptDocHit>> docHitStat(@Validated @RequestBody ChatRptDocHitSearchVo search) {
        search.setTenantId(KefuContext.getTid());
        Page<ChatRptDocHit> page = chatRptDocHitService.selectGroupByDate(search);
        return ResultGenerator.genSuccessResult(page);
    }

    @PostMapping("/docHitStatExport")
    @ApiOperation(value = "导出机器人词条命中统计", notes = "导出机器人词条命中统计")
    public void docHitStatExport(@Validated @RequestBody ChatRptDocHitSearchVo search, HttpServletResponse response) throws IOException {
        if (search.getResultDateStart()==null || search.getResultDateEnd()==null) {
            return;
        }
        search.setTenantId(KefuContext.getTid());
        Page<ChatRptDocHit> page = chatRptDocHitService.selectGroupByDate(search);
        List<Object[]> exportList = new ArrayList<>();
        Object[] title = {msg("标准问法"),msg("命中次数"),msg("所属分类")};
        exportList.add(title);
        for (ChatRptDocHit i : page.getRecords()) {
            Object[] row = {i.getDocQuestion(), i.getDocCount(), i.getDocTypeName()};
            exportList.add(row);
        }
        csvWriter(exportList, response);
    }

    @PostMapping("/getAdminStatus")
    @ApiOperation(value = "查询客服状态纪录", notes = "页面传递statusTime，DESC排序，返回值statusDuration，updateTime不用显示")
    public Result<Page<ChatAdminStatus>> getAdminStatus(@Validated @RequestBody ChatAdminStatusSearchVo search) {
        Page<ChatAdminStatus> list = chatAdminStatusService.searchLambdaPage(search);
        Map<String, String> userMap = sysUserMapper.getUserNameMap(KefuContext.getTid());
        List<BasicStatusConfig> basicStatusConfigList = basicStatusConfigMapper.selectList(Wrappers.lambdaQuery(BasicStatusConfig.class)
                .eq(BasicStatusConfig::getTenantId, KefuContext.getTid())
                .eq(BasicStatusConfig::getStatusType, 1));
        Map<String, String> statusMap = basicStatusConfigList.stream().collect(Collectors.toMap(BasicStatusConfig::getStatusCode, BasicStatusConfig::getStatusName));
        list.getRecords().forEach(item -> {
            item.setAdminName(userMap.get(item.getAdminId()));
            item.setStatusName(statusMap.get(String.valueOf(item.getStatusType())));
        });
        return ResultGenerator.genSuccessResult(list);
    }

    @PostMapping("/exportAdminStatus")
    @ApiOperation(value = "导出客服状态纪录", notes = "页面传递statusTime，DESC排序，返回值statusDuration，updateTime不用显示")
    public void getAdminStatus(@Validated @RequestBody ChatAdminStatusSearchVo search
            , HttpServletResponse response) throws IOException {
        Page<ChatAdminStatus> list = chatAdminStatusService.searchLambdaPage(search);
        Map<String, String> userMap = sysUserMapper.getUserNameMap(KefuContext.getTid());
        List<BasicStatusConfig> basicStatusConfigList = basicStatusConfigMapper.selectList(Wrappers.lambdaQuery(BasicStatusConfig.class)
                .eq(BasicStatusConfig::getTenantId, KefuContext.getTid())
                .eq(BasicStatusConfig::getStatusType, 1));
        Map<String, String> statusMap = basicStatusConfigList.stream().collect(Collectors.toMap(BasicStatusConfig::getStatusCode, BasicStatusConfig::getStatusName));
        list.getRecords().forEach(item -> {
            item.setAdminName(userMap.get(item.getAdminId()));
            item.setStatusName(statusMap.get(String.valueOf(item.getStatusType())));
        });
        List<Object[]> exportList = new ArrayList<>();
        Object[] title = {msg("客服名称"),msg("状态变更时间"),msg("状态")};
        exportList.add(title);
        for (ChatAdminStatus i : list.getRecords()) {
            Object[] row = {i.getAdminName(), DateUtils.dateTimeFormat(i.getStatusTime()), i.getStatusName()};
            exportList.add(row);
        }
        csvWriter(exportList, response);
    }

    @PostMapping("/getRealTimeData")
    @ApiOperation(value = "查询在线实时接待数据", notes = "查询在线实时接待数据")
    public Result<ChatRealTimeData> getRealTimeData() {
        return ResultGenerator.genSuccessResult(chatReportService.getRealTimeData(KefuContext.getKefuContext().getTenantId()));
    }

    @PostMapping("/timeSharingRpt")
    @ApiOperation(value = "分时段统计", notes = "分时段统计")
    public Result<Page<ChatTimeSharingRptVo>> timeSharingRpt(@Validated @RequestBody ChatTimeSharingRptSearchVo search) {
        if (search.getStartTime() == null || search.getEndTime() == null) {
            return ResultGenerator.genValidFailResult();
        }
        Page<ChatTimeSharingRptVo> result = chatRptAdminWorkService.timeSharingRpt(search);
        return ResultGenerator.genSuccessResult(result);
    }


    @PostMapping("/exportTimeSharingRpt")
    @ApiOperation(value = "分时段统计", notes = "分时段统计")
    public void exportTimeSharingRpt(@Validated @RequestBody ChatTimeSharingRptSearchVo search, HttpServletResponse response) throws IOException {
        chatRptAdminWorkService.exportTimeSharingRpt(search, response);
    }

    @PostMapping("/likeAndAtepOn")
    @ApiOperation(value = "点赞点踩统计", notes = "点赞点踩分时段统计")
    public Result<Page<LikeAndAtepOnResultVO>> likeAndAtepOn(@Validated @RequestBody LikeAndAtepOnSeachVO likeAndAtepOnSeachVO) {
        Page<LikeAndAtepOnResultVO> result = robotDocCommentService.likeAndAtepOn(likeAndAtepOnSeachVO);

        return ResultGenerator.genSuccessResult(result);
    }

    @PostMapping("/likeAndAtepOnDetial")
    @ApiOperation(value = "点赞点踩详情统计", notes = "点赞点踩分时段详情统计")
    public Result<Page<likeAndAtepOnDetialResult>> likeAndAtepOnDetial(@Validated @RequestBody LikeAndAtepOnDetialVO likeAndAtepOnDetialVO) {
        Page<likeAndAtepOnDetialResult> result = robotDocCommentService.likeAndAtepOnDetial(likeAndAtepOnDetialVO);

        return ResultGenerator.genSuccessResult(result);
    }


    @PostMapping("chatSkillsetsWorkloadList")
    @ApiOperation(value = "技能组工作量统计", notes = "技能组工作量统计")
    public Result<List<ChatSkillsetsWorkLoadVo>> chatSkillsetsWorkloadList(@Validated @RequestBody ChatSkillsetsWorkloadSearchVo param) {
        return ResultGenerator.genSuccessResult(chatReportService.chatSkillsetsWorkloadList(param));
    }

    @PostMapping("exportChatSkillsetsWorkload")
    @ApiOperation(value = "技能组工作量统计导出", notes = "技能组工作量统计导出")
    public void exportChatSkillsetsWorkload(@Validated @RequestBody ChatSkillsetsWorkloadSearchVo param, HttpServletResponse response) throws IOException {
        chatReportService.exportChatSkillsetsWorkload(param, response);
    }

}
